package com.zzyl.controller.customer;

import com.zzyl.base.ResponseResult;
import com.zzyl.dto.UserLoginRequestDto;
import com.zzyl.service.MemberService;
import com.zzyl.vo.LoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * 用户管理
 */

/**
 * 微信小程序通过开发者服务器与微信接口服务（Wechat Http Api）之间的交互流程，以实现登录和业务请求的功能
 * 登录流程
 * 1.小程序端发起登录请求
 * 小程序（MiniProgram）调用wx.login()接口获取code。
 * 然后通过wx.request()将code发送到开发者服务器。
 * 2.开发者服务器与微信接口服务交互
 * 开发者服务器收到code后，将其与appid和appsecret一起发送到微信接口服务的登录凭证校验接口。
 * 微信接口服务校验后返回session_key和openid等信息。
 * 3.开发者服务器处理登录态
 * 开发者服务器根据收到的openid和session_key等自定义登录态。
 * 并将自定义登录态返回给小程序。
 * 4.小程序存储登录态
 * 小程序收到自定义登录态后，将其存入storage中。
 *
 * 业务请求流程
 * 1.小程序发起业务请求
 * 小程序在发起业务请求时，通过wx.request()携带之前存储的自定义登录态。
 * 2.开发者服务器验证并处理请求
 * 开发者服务器收到业务请求后，通过自定义登录态查询对应的openid和session_key。
 * 根据查询结果处理业务请求，并返回业务数据给小程序。
 */
@Slf4j
@Api(tags = "客户管理")
@RestController
@RequestMapping("/customer/user")
public class CustomerUserController {

    @Autowired
    private MemberService memberService;

    /**
     * C端用户登录--微信登录
     * @param userLoginRequestDto 用户登录信息，包含微信登录所需的code和phoneCode
     * @return 登录结果
     * 调用 wx.login() 获取 临时登录凭证code ，并回传到开发者服务器
     * 临时登录凭证 code：
     *      只能使用一次，用完即失效
     *      调用 wx.login() 时由微信客户端生成
     *      有效期：5分钟（官方文档说明）
     *      目的：为了安全地换取 openid 和 session_key
     *      不要在前端存储code - 获取后立即发送到服务器
     * 手机号临时凭证 phoneCode：
     *      特性	        说明
     *      生成方	    微信小程序客户端
     *      用途	        换取用户手机号
     *      有效期	    5分钟
     *      使用次数	    只能使用一次
     *      需要授权	    必须用户明确同意
     *      与登录凭证 code 的机制类似，都是"用临时凭证换真实数据"的安全模式
     *
     * 安全模式的目的：
     *      这个"用临时凭证换真实数据"的安全模式主要是防开发者（也就是您），而不是防用户或微信
     * 谁能获得真实手机号？
     *      微信平台 ✅
     *      拥有：用户的真实手机号
     *      能做：验证临时凭证并返回真实手机号给合法的开发者
     *      开发者服务器 ✅
     *      能够：通过正规API从微信获取真实手机号
     *      需要：用户授权 + 临时凭证 + 合法的 appsecret
     *      小程序前端 ❌
     *      只能：获取临时凭证code
     *      不能：直接获取真实手机号
     * 微信平台始终拥有用户的真实手机号，开发者服务器可以通过正规API从微信平台获取真实手机号，而小程序前端永远无法直接获取真实手机号。
     * 用户授权 -> 小程序生成 code + phoneCode -> 小程序将code发送至开发者服务器 -> 开发者服务器调用微信API ->
     * 微信平台返回用户真实手机号、openId、session_key至开发者服务器 -> 将数据存储至开发者数据库
     */
    @PostMapping("/login")
    @ApiOperation("小程序端登录")
    public ResponseResult<LoginVo> login(@RequestBody UserLoginRequestDto userLoginRequestDto){
        LoginVo loginVo = memberService.login(userLoginRequestDto);
        return ResponseResult.success(loginVo);
    }

}